<script setup lang="ts">
import FormTemplate from '@/components/FormTemplate.vue'
import { useCommonStore } from '@/store/main'
import { setPasswordRqs } from '@/request/api'
import { Utils } from '@/common/utils.js'
import { sha256 } from 'js-sha256'
import { INJECT_THEME_COLOR } from '@/common/provideType'
import type { FormRules } from 'element-plus'
import type { FormIntType, FormType, FormConfigType } from '@/components/formTemplateType'

const { isFirstLogin, isShowReset = false } = defineProps<{isFirstLogin: boolean, isShowReset?: boolean}>()
const $router = useRouter()
const $store = useCommonStore()
const vPreventReClick = inject('vPreventReClick')
const THEME_COLOR = inject(INJECT_THEME_COLOR)
const formTemplateRef = ref<InstanceType<typeof FormTemplate>>()
const successMessage = '密码修改成功，请重新登陆。'
const formConfig: FormConfigType = {
	isFirstLogin,
	labelWidth: '120px',
	formItems: [
		{
			type: 'password',
			key: 'oldPassword',
			value: '',
			label: '旧密码',
			placeholder: '请输入旧密码',
			maxLength: 16
		}, {
			type: 'password',
			key: 'newPassword',
			value: '',
			label: '新密码',
			placeholder: '请输入新密码',
			maxLength: 16
		}, {
			type: 'password',
			key: 'repeatNewPassword',
			value: '',
			label: '重复密码',
			placeholder: '请输入重复输入新密码',
			maxLength: 16
		}
	]
}
const formConfigKey: FormIntType = {}
const formData: FormType = reactive({})
formConfig.formItems?.forEach(item => formConfigKey[item.key] = item.value)
Object.assign(formData, formConfigKey)

/**
 * 表单校验
 */
const validateOldPassword = (
	rule: any,
	value: any,
	callback: any
) => {
	if(!value) return callback(new Error('请输入旧密码'))
	if(value.length < 6) return callback(new Error('旧密码长度不能少于6位'))
	callback()
}
const validateNewPassword = (
	rule: any,
	value: any,
	callback: any
) => {
	if(!value) return callback(new Error('请输入新密码'))
	if(value.length < 6) return callback(new Error('新密码长度不能少于6位'))
	callback()
}
const validateRepeatNewPassword = (
	rule: any,
	value: any,
	callback: any
) => {
	if(!value) return callback(new Error('请再次输入新密码'))
	if(value.length < 6) return callback(new Error('重复密码长度不能少于6位'))
	if(formData.newPassword !== formData.repeatNewPassword) return callback(new Error('两次重复密码不一致'))
	callback()
}
const rules = reactive<FormRules<typeof formData>>({
	oldPassword: [
		{required: true, validator: validateOldPassword, trigger: 'blur'}
	],
	newPassword: [
		{required: true, validator: validateNewPassword, trigger: 'blur'}
	],
	repeatNewPassword: [
		{required: true, validator: validateRepeatNewPassword, trigger: 'blur'}
	]
})

/**
 * 将输入的字符串转换为每个字符的ASCII码的两位小写十六进制表示的字符串
 * 并将所有字符的结果拼接返回
 */
const stringToHex = (str: string): string => {
	let res = '', len = str.length
	for(let i = 0; i < len; i++) {
		res += ((str.charCodeAt(i) & 0xf0) / 16).toString(16);
		res += ((str.charCodeAt(i) & 0x0f)).toString(16);
	}
	return res
}

/**
 * 确认提交表单
 */
const onSubmitFn = () => {
	const formEl = formTemplateRef.value?.formRef
	if(!formEl) return
	formEl.validate(async valid => {
		if(!valid) return
		const userName = $store.userInfo.userName!
		const nonce = Utils.generateMixStrFn()
		const timeUTC = Math.ceil(Utils.getDate().getUTC / 1000)
		const secretPassword = Utils.xorEncrypt(formData.newPassword, formData.oldPassword)
		const newPasswordHex = stringToHex(secretPassword)
		const hash = sha256.create()
		hash.update(`${userName}_${formData.oldPassword}_${formData.newPassword}_${newPasswordHex}_${nonce}_${timeUTC}`)
		const signHex = hash.hex()
		const res = await setPasswordRqs({
			user_name: userName,
			nonce,
			ts: timeUTC,
			secret_key: newPasswordHex,
			sign: signHex
		})

		if(res?.code === 0) {
			$store.setToken('')
			$router.push({path: '/login'})
		}
	})
}

/**
 * 重置表单
 */
const onResetFn = () => formTemplateRef.value?.resetForm()
</script>

<template>
	<div class="password-bar">
		<FormTemplate 
			ref="formTemplateRef" 
			v-bind="formConfig" 
			:rules="rules" 
			v-model:formData="formData" 
		>
			<template #footer>
				<el-form-item :class="`${isFirstLogin ? '' : 'pl-120'}`">
					<el-button 
						v-preventReClick 
						:class="[`btn btn-${THEME_COLOR}`]" 
						@click="onSubmitFn"
					>确定</el-button>
				</el-form-item>

				<el-form-item v-if="isShowReset" :class="`${isFirstLogin ? '' : 'pl-120'}`">
					<el-button class="btn" @click="onResetFn">重置</el-button>
				</el-form-item>
			</template>
		</FormTemplate>
	</div>
</template>

<style lang="scss" scoped>
.password-bar {
	:deep(.el-form) {
		label.el-form-item__label {
			display: inline-block;
			text-indent: 0;
			text-align: right;
		}
	}
	.pl-120 {
		padding-left: 1.2rem;
	}
	.btn {
		width: 100%;
		height: .4rem;
	}
	.icon-eye {
		position: absolute;
		right: 0;
		height: 100%;
		width: .3rem;
		cursor: pointer;
	}
}
</style>